import traceback

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from ftplib import FTP

from rest_framework.response import Response
from rest_framework import views, status

from ImageBed.models import ImageBedRecord
from ImageBed.serializer import HistorySerializer
from Main.utils import dayUtils, chineseNameUtil
import json
import os
from django.conf import settings


# 获取ftp服务器相关信息
def getFtpInfo():
    with open(os.path.join(settings.BASE_DIR, 'env.json')) as env:
        ENV = json.load(env)
    host = ENV['ftp_config']['host']
    port = ENV['ftp_config']['port']
    username = ENV['ftp_config']['ftp_user']
    password = ENV['ftp_config']['ftp_password']
    image_bed_path = ENV['ftp_config']['image_bed_path']
    image_bed_relative_path = ENV['ftp_config']['image_bed_relative_path']
    return host, port, username, password, image_bed_path, image_bed_relative_path


# Create your views here.
class UploadView(views.APIView):
    def post(self, request):
        try:
            with open(os.path.join(settings.BASE_DIR, 'env.json')) as env:
                ENV = json.load(env)
            file = request.FILES.get('file')
            host, port, username, password, image_bed_path, image_bed_relative_path = getFtpInfo()
            file_name = file.name
            file_size = str(file.size / 1000)
            # 图床地址
            image_bed_path = image_bed_path
            # 处理文件中文问题
            if chineseNameUtil.is_contain_chinese(file_name):
                new_file_name = chineseNameUtil.rename(file_name).replace(' ', '')
            else:
                new_file_name = file_name.replace(' ', '')
            # 目录名
            dir_name = dayUtils.get_year() + dayUtils.get_month() + dayUtils.get_day()
            # 路径名 ftp客户端不支持多级目录
            ftp_path = "./{}/".format(dir_name)

            ftp = ftp_connect(host, port, username, password)
            # 上传文件，第一个是要上传到ftp服务器路径下的文件，第二个是本地要上传的的路径文件
            ftp.cwd(image_bed_relative_path)
            if dir_name not in ftp.nlst():
                ftp.mkd(ftp_path)
            upload_file(ftp, ftp_path + new_file_name, file)
        except Exception as e:
            print(traceback.format_exc())
            return JsonResponse({
                "res_code": -1,
                "res_msg": "ftp错误！错误原因：{}".format(repr(e)),
            })
        print(ftp.getwelcome())  # 打印出欢迎信息
        # 获取当前路径
        pwd_path = ftp.pwd()
        print("FTP当前路径:", pwd_path)
        # 设置FTP当前操作的路径
        ftp.cwd(dir_name)
        # 返回一个文件名列表
        filename_list = ftp.nlst()
        if new_file_name in filename_list:
            file_path = "http://{}/{}/{}/{}".format(host, image_bed_path, dir_name, new_file_name)
            print("上传成功，图片已上传至：{}".format(file_path))
            try:
                record_instance = ImageBedRecord()
                record_instance.image_path = file_path
                record_instance.article_id = ""
                record_instance.origin_image_name = file_name
                record_instance.new_image_name = new_file_name
                record_instance.image_size = file_size
                record_instance.save()
            except Exception as e:
                print(traceback.format_exc())
                return JsonResponse({
                    "res_code": -1,
                    "res_msg": "上传记录进数据库错误！错误原因：{}".format(repr(e)),
                })
            return JsonResponse({
                "res_code": 0,
                "file_info": {
                    "file_path": file_path,
                    "old_file_name": file_name,
                    "new_file_name": new_file_name
                }
            })
        else:
            print("图片上传失败")
            return JsonResponse({
                "res_code": -1,
                "res_msg": "图片上传失败！",
                "file_path": "",
                "filename_list": filename_list,
            })


# 隐藏
class HiddenView(views.APIView):
    def post(self, request):
        pics_list = request.data
        if pics_list:
            for picId in pics_list:
                try:
                    pic_instance = ImageBedRecord.objects.get(pk=picId, is_delete=False, is_show=True)
                except Exception as e:
                    if 'DoesNotExist' in format(repr(e)):
                        e = '记录不存在，无法删除！'
                    return JsonResponse({
                        "res_code": status.HTTP_204_NO_CONTENT,
                        "res_msg": format(repr(e))
                    })
                pic_instance.is_show = False
                pic_instance.save()
                return JsonResponse({
                    "res_code": status.HTTP_200_OK,
                    "res_msg": '已隐藏'
                })


# 删除
class DeleteView(views.APIView):

    def post(self, request):
        pics_list = request.data
        if pics_list:
            for picId in pics_list:
                try:
                    pic_instance = ImageBedRecord.objects.get(pk=picId, is_delete=False, is_show=True)
                except Exception as e:
                    if 'DoesNotExist' in format(repr(e)):
                        e = '记录不存在，无法删除！'
                    return JsonResponse({
                        "res_code": status.HTTP_204_NO_CONTENT,
                        "res_msg": format(repr(e))
                    })
                image_path = pic_instance.image_path
                image_name = pic_instance.new_image_name
                is_success, msg = delete_file(image_path, image_name)
                if not is_success:
                    return JsonResponse({
                        "res_code": status.HTTP_500_INTERNAL_SERVER_ERROR,
                        "res_msg": msg
                    })
                # 将is_delete状态置为1
                pic_instance.is_delete = True
                pic_instance.save()
        return JsonResponse({
            "res_code": status.HTTP_200_OK,
            "res_msg": '已删除'
        })


def delete_file(image_path, image_name):
    host, port, username, password, image_bed_path, image_bed_relative_path = getFtpInfo()
    ftp = ftp_connect(host, port, username, password)
    # 要取文件的日期路径，先对文件名分割取前半部，再对图床路径分割取后半部就能得到20220513
    # http://IP/image/media/image_bed/20220513/filename.png
    dir_name = image_path.split(image_name)[0].split(image_bed_path)[1].replace('/', '')
    try:
        ftp.cwd(image_bed_relative_path)
        ftp.cwd(dir_name)
        file_list = ftp.nlst()
        print(file_list)
        print(image_name)
        print(image_name in file_list)
        if image_name in file_list:
            print(1111111111111)
            ftp.delete(image_name)
            return True, 'success'
        else:
            return False, '图片文件不存在！'
    except Exception as e:
        print(traceback.format_exc())
        return False, format(repr(e))


# 连接ftp
def ftp_connect(host, port, username, password):
    ftp = FTP()
    # 打开调试级别2，显示详细信息
    # ftp.set_debuglevel(2)
    ftp.connect(host, port)
    ftp.login(username, password)
    return ftp


# 从本地上传文件到ftp
def upload_file(ftp, remote_path, file):
    buff_size = 1024
    ftp.storbinary('STOR ' + remote_path, file, buff_size)
    ftp.set_debuglevel(0)
    file.close()


# 获取历史记录
class HistoryView(views.APIView):

    @staticmethod
    def get(request):
        try:
            # 取有效数据
            record_instance_list = ImageBedRecord.objects.all().filter(is_show=True).filter(is_delete=False)
            # 序列化
            record_list = HistorySerializer(record_instance_list, many=True)
            for i in record_list.data:
                # 修改一下时间的格式
                i['upload_time'] = i['upload_time'][:19].replace('T', ' ')
                if i['image_size'] is not None:
                    i['image_size'] = i['image_size'].split('.')[0]
            return Response({
                "res_code": 0,
                "data": record_list.data
            })
        except Exception as e:
            return Response({
                "res_code": -1,
                "res_msg": "错误！原因：{}".format(repr(e))
            })
